﻿package stuff3D.meshes
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.net.FileReference;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.ui.Keyboard;
	import flash.utils.ByteArray;
	import stuff3D.textures.Texture;
	
	public class Mesh
	{
		static public var file_delimiter1:String = "\r";
		static public var file_delimiter2:String = ",";		
		
		public var bmp:Bitmap;
		
		public var vertices:Vector.<Vector3D>;
		public var triangles:Vector.<Triangle>;
		public var indices:Vector.<int>;
		public var uvtData:Vector.<Number>;
		public var uvdots:Vector.<Point>;
		public var rendererMesh:Mesh;
		
		public function Mesh():void 
		{
			bmp = Texture.getTexture(5);
		}
		private function clean():void 
		{
		}
		
		public function load_mesh( url:String, onCompleteHandler:Function=null ):void
		{
			var urlloader:URLLoader = new URLLoader();
			urlloader.load( new URLRequest( url ) );
			urlloader.addEventListener( Event.COMPLETE, meshloaded );
			if ( onCompleteHandler != null ) urlloader.addEventListener( Event.COMPLETE, onCompleteHandler );
		}
		private function meshloaded(e:Event):void 
		{
			trace("mesh loaded ... " + e.currentTarget.data);
			clean();
			info = e.currentTarget.data;
		}
		public function get xml_bytes():ByteArray
		{
			XML.prettyPrinting = true;
			var ba:ByteArray = new ByteArray();
			ba.writeUTFBytes( info );
			return ba;
		}
		public function get info():String
		{
			var s:String = "";
			s += "Mesh";
			//for each( var mDot:Vector3D in vertices ) s += mDot.y + file_delimiter2;
			return s;
		}
		public function set info(s:String):void
		{
			var arrayFile:Array = s.split( file_delimiter1 );
			//populate( arrayFile[ 2 ].split( file_delimiter2 ) );
		}
		
		// triangle geometry

		public function isVisible(p1:Vector3D, p2:Vector3D, p3:Vector3D):Boolean
		{
			return (p2.x - p1.x) * (p3.y - p1.y) < (p3.x - p1.x) * (p2.y - p1.y);
		}
		public function crossProduct(triangle:Triangle):Vector3D
		{
			var v0:Vector3D = vertices[ triangle.indices[ 0 ] ];
			var v1:Vector3D = vertices[ triangle.indices[ 1 ] ];
			var v2:Vector3D = vertices[ triangle.indices[ 2 ] ];
			var vec1:Vector3D = v1.subtract( v0 );
			var vec2:Vector3D = v2.subtract( v0 );
			return vec2.crossProduct( vec1 );
		}		
		public function normale(triangle:Triangle):Vector3D
		{
			var cross:Vector3D = crossProduct( triangle );
			cross.normalize();
			return cross;
		}
		public function twice_area(triangle:Triangle):Number
		{
			var cross:Vector3D = crossProduct( triangle );
			var norm:Vector3D = cross.clone();
			//norm.scaleBy( cross.length );
			norm.normalize();
			var area:Number = norm.dotProduct( cross );
			return area;
		}		
		public function triangle_barycenter(triangle:Triangle):Vector3D// moyenne des 3 points ?
		{
			var v0:Vector3D = vertices[ triangle.indices[ 0 ] ];
			var v1:Vector3D = vertices[ triangle.indices[ 1 ] ];
			var v2:Vector3D = vertices[ triangle.indices[ 2 ] ];
			return new Vector3D( ( v0.x + v1.x + v2.x ) / 3, ( v0.y + v1.y + v2.y ) / 3, ( v0.z + v1.z + v2.z ) / 3 );
		}
		public function distance_origin(triangle:Triangle):Number
		{
			var v0:Vector3D = vertices[ triangle.indices[ 0 ] ];
			var v1:Vector3D = vertices[ triangle.indices[ 1 ] ];
			var v2:Vector3D = vertices[ triangle.indices[ 2 ] ];
			var n:Vector3D = normale( triangle );
			
			//trace( "distance_origin(triangle:Triangle)" );
			//trace( - ( n.x * v0.x + n.y * v0.y + n.z * v0.z ) );
			//trace( - ( n.x * v1.x + n.y * v1.y + n.z * v1.z ) );
			//trace( - ( n.x * v2.x + n.y * v2.y + n.z * v2.z ) );
			
			return - ( n.x * v0.x + n.y * v0.y + n.z * v0.z );
		}	
		public function wich_side(v:Vector3D, triangle:Triangle):Boolean
		{
			return normale( triangle ).dotProduct( v ) - distance_origin( triangle ) > 0;
		}		
	}
}